package com.df.excel_export.excel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.df.excel_export.common.*;
import com.df.excel_export.excel_table.ExcelTableStructure;
import com.df.excel_export.excel_table.HHeader;
import com.df.excel_export.project_config.ProjectConfig;

import java.util.*;
import java.util.stream.Collectors;

public class ExcelTableDataReadListener implements ReadListener<Map<Integer, String>> {

    boolean canContinue = true;
    int rowNum = 0;
    int dataRowNum = 0;
    String tableType = Constant.TableType.Horizontal;

    ProjectConfig cfg;
    ExcelTableStructure structure = null;
    public ExcelTableDataReadListener(ProjectConfig baseConfig, int parseType) {
        this.cfg = baseConfig;
    }

    @Override
    public void invoke(Map<Integer, String> rowData, AnalysisContext analysisContext) {
        if(structure==null){
            String absolutePath = analysisContext.readWorkbookHolder().getFile().getAbsolutePath();
            Map<String, ExcelTableStructure> map = ExcelTableManager.projectExcelMetaCaches.get(cfg.getName());
            ExcelTableStructure structure = map.get(absolutePath);
            this.structure = structure;
        }


        rowNum++;
        if(structure.getTable().getStartRow()!=null && structure.getTable().getStartRow()<dataRowNum){
            return;
        }
        //横表  竖表
        //TODO 根据表的类型进行不同处理
        if (tableType == Constant.TableType.Horizontal) {//横表
            handleHorizontalTable(rowData);
            return;
        }
        handleVerticalTable(rowData);
    }


    private void handleVerticalTable(Map<Integer, String> rowData) {

    }

    private void handleHorizontalTable(Map<Integer, String> rowData) {
        int size = rowData.size();
        List<Object> row = new ArrayList<>();
        List<HHeader> hHeaders = structure.getTable().getHHeaders();
        for (int i = 1; i < size; i++) {
            if(!canContinue){
                ExportTask.nowTask.setCanContinue(false);
                break;
            }
            HHeader hHeader = hHeaders.get(i-1);
            String dataStr = rowData.get(i);
            String typeStr = hHeader.getType();
            if(typeStr.equals("bool")){
                parseBoolCell(dataStr,row,i);
                continue;
            }
            if(typeStr.equals("int")){
                parseIntCell(dataStr,row,i);
                continue;
            }
            if(typeStr.equals("long")){
                parseLongCell(dataStr,row,i);
                continue;
            }
            if(typeStr.equals("string")){
                if(dataStr==null){
                    dataStr = "";
                }
                row.add(dataStr);
                continue;
            }
            if(typeStr.endsWith("[][]")){//二维数组
                parseBoubleArrayCell(dataStr,typeStr,row,i);
                continue;
            }
            if(typeStr.endsWith("[]")){//一维数组
                String elementType = typeStr.replace("[]", "");
                List<?> result = parseArrayCell(dataStr,elementType,i,false);
                row.add(result);
                continue;
            }

            if(typeStr.startsWith("@")){//枚举类型
                //枚举同意替换成枚举字段的序列值
                parseEnumCell(dataStr,typeStr,row,i);
                continue;
            }
        }
//        excelTable.getDatas().add(row);
//        boolean addResult = excelTable.addRowData(row);
//        if(!addResult){
//            canContinue = false;
//        }
    }

    private void parseBoolCell(String dataStr, List<Object> row, int i) {
        if(dataStr==null||dataStr.isEmpty()){
            row.add(false);
        }else {
            if(!dataStr.equals("0")){
                row.add(true);
            }
        }
    }

    private void parseEnumCell(String dataStr, String typeStr, List<Object> row, int i) {
        String replace = typeStr.replace("@", "");
        int lIndex = replace.indexOf("(");
        int enumValueIndex = 2;
        String enumName = replace;
        if(lIndex!=-1){
            enumName = replace.substring(0,lIndex);
            String enumValueIndexStr = replace.substring(lIndex).replace("(","").replace(")","");
            if(!enumValueIndexStr.isEmpty()){
                try {
                    enumValueIndex = Integer.parseInt(enumValueIndexStr);
                }catch (Exception e){
                    e.printStackTrace();
                    canContinue = false;
//                    ExcelTools.addErrorMsg("枚举值索引解析失败："+errorCellMsg(excelTable.getExcelFilePath(),excelTable.getSheetName(),rowNum,i)+" 解析的枚举类型："+typeStr);
                }

            }
        }
//        ExcelEnum excelEnum = ExcelTableManager.enums.get(enumName);
//        if(excelEnum==null){
//            canContinue = false;
////            ExcelTools.addErrorMsg("没有定义枚举类型："+enumName+errorCellMsg(excelTable.getExcelFilePath(),excelTable.getSheetName(),rowNum,i));
//            return;
//        }
//        if(enumValueIndex==1){//单元格的内容为枚举字段名
//            Optional<EnumFiled> any = excelEnum.getFileds().stream().filter(enumFiled -> enumFiled.getFiledName().equals(dataStr)).findAny();
//            if(!any.isPresent()){
//                canContinue = false;
//                ExcelTools.addErrorMsg("单元格的值 "+dataStr+" 未在枚举定义的字段中："+enumName+errorCellMsg(excelTable.getExcelFilePath(),excelTable.getSheetName(),rowNum,i));
//                return;
//            }
//            row.add(any.get().getValue());
//            return;
//        }
//        if(enumValueIndex==2){//单元格内容为枚举字段序列号
//            Integer enumValue = null;
//            try {
//                enumValue = Integer.parseInt(dataStr);
//            }catch (Exception e){
//                e.printStackTrace();
//                canContinue = false;
//                ExcelTools.addErrorMsg("单元格的值 "+dataStr+" 无法解析成枚举字段序列号："+enumName+errorCellMsg(excelTable.getExcelFilePath(),excelTable.getSheetName(),rowNum,i));
//                return;
//            }
//            Integer finalEnumValue = enumValue;
//            Optional<EnumFiled> any = excelEnum.getFileds().stream().filter(enumFiled -> enumFiled.getValue()== finalEnumValue).findAny();
//            if(!any.isPresent()){
//                canContinue = false;
//                ExcelTools.addErrorMsg("单元格的序列号值 "+dataStr+" 未在枚举定义的字段中："+enumName+errorCellMsg(excelTable.getExcelFilePath(),excelTable.getSheetName(),rowNum,i));
//                return;
//            }
//            row.add(enumValue);
//            return;
//        }
//
//        if(enumValueIndex==3){//单元格内容为枚举中文名
//            Optional<EnumFiled> any = excelEnum.getFileds().stream().filter(enumFiled -> enumFiled.getFileName_CN().equals(dataStr)).findAny();
//            if(!any.isPresent()){
//                canContinue = false;
//                ExcelTools.addErrorMsg("单元格的值 "+dataStr+" 未在枚举定义的中文名中："+enumName+errorCellMsg(excelTable.getExcelFilePath(),excelTable.getSheetName(),rowNum,i));
//                return;
//            }
//            row.add(any.get().getValue());
//            return;
//        }

    }

    private List<?> parseArrayCell(String dataStr, String elemntType, int colIndex,boolean isDbArray) {
        String trueType = "一维数组";
        if(isDbArray){
            trueType = "二维数组";
        }
        //int long float
        if(dataStr==null||dataStr.isEmpty()){
            return new ArrayList<>();
        }
        String[] array = dataStr.split("\\+");
        if(elemntType.equals("bool")){
            List<Boolean> innerList = new ArrayList<Boolean>();
            for (String s : array) {
                if(s.isEmpty() || s.equals("0")){
                    innerList.add(false);
                }else{
                    innerList.add(true);
                }
            }
            return innerList;
        }
        if(elemntType.equals("int")){
            List<Integer> innerList = new ArrayList<Integer>();
            for (String s : array) {
                try {
                    innerList.add(Integer.parseInt(s));
                }catch (Exception e){
                    e.printStackTrace();
                    canContinue = false;
//                    ExcelTools.addErrorMsg(trueType+"int类型元素解析失败:"+errorCellMsg(excelTable.getExcelFilePath(), excelTable.getSheetName(),rowNum,colIndex)+" 解析字符串："+s);
                    break;
                }

            }

            return innerList;
        }
        if(elemntType.equals("long")){
            List<Long> interList = new ArrayList<Long>();
            for (String s : array) {
                try {
                    interList.add(Long.parseLong(s));
                }catch (Exception e){
                    e.printStackTrace();
                    canContinue = false;
//                    ExcelTools.addErrorMsg(trueType+"long类型元素解析失败:"+errorCellMsg(excelTable.getExcelFilePath(), excelTable.getSheetName(),rowNum,colIndex)+" 解析字符串："+s);
                    break;
                }
            }
            return interList;
        }
        canContinue = false;

//        ExcelTools.addErrorMsg(trueType+"未支持的元素类型，解析失败:"+errorCellMsg(excelTable.getExcelFilePath(), excelTable.getSheetName(),rowNum,colIndex)+" 解析元素类型："+elemntType);
        return new ArrayList<>();
    }

    private void parseBoubleArrayCell(String dataStr, String typeStr, List<Object> row, int colIndex) {
        //int long float
        String baseType = typeStr.replace("[", "").replace("]", "").trim();
        if(dataStr==null||dataStr.isEmpty()){
            row.add(new ArrayList<>());
            return;
        }
        String[] outerArray = dataStr.split(";");
        List<List<?>> list  = new ArrayList<>();


        out:for (String interArrayStr : outerArray) {
            if(interArrayStr==null||interArrayStr.isEmpty()){
                list.add(new ArrayList<>());
                continue ;
            }
            List<?> parseResult = parseArrayCell(interArrayStr,baseType,colIndex,true);
            list.add(parseResult);
        }
        row.add(list);
    }

    private void parseLongCell(String dataStr, List<Object> row, int i) {
        if(dataStr==null||dataStr.isEmpty()){
            row.add(0L);
        }else {
            try {
                row.add(Long.parseLong(dataStr));
            }catch (Exception e){
                e.printStackTrace();
                canContinue = false;
//                ExcelTools.addErrorMsg("long类型数据解析失败："+errorCellMsg(excelTable.getExcelFilePath(), excelTable.getSheetName(),rowNum,i));
            }
        }
    }

    private void parseIntCell(String dataStr, List<Object> row, int i) {
        if(dataStr==null||dataStr.isEmpty()){
            row.add(0);
        }else {
            try {
                row.add(Integer.parseInt(dataStr));
            }catch (Exception e){
                e.printStackTrace();
                canContinue = false;
//                ExcelTools.addErrorMsg("int类型数据解析失败："+errorCellMsg(excelTable.getExcelFilePath(), excelTable.getSheetName(),rowNum,i));
            }
        }
    }

    private void handleTableHead(Map<Integer, String> rowData) {
        String s = rowData.get(0);
        if (s == null || s.isEmpty()) {
            return;
        }
        if (s.equals("filed_name")) {
            //升序排
            int size = rowData.size();
            for (int i = 1; i < size; i++) {
//                excelTable.getFieldNames().add(rowData.get(i));
            }
            return;
        }
        if (s.equals("filed_type")) {
            //升序排
            int size = rowData.size();
            for (int i = 1; i < size; i++) {
//                excelTable.getFieldTypes().add(rowData.get(i).trim());
            }
            return;
        }
        if (s.equals("group")) {
            //升序排
            int size = rowData.size();
            for (int i = 1; i < size; i++) {
                String groupStr = rowData.get(i);
                String[] split = groupStr.split(",");
                List<String> groupList = Arrays.stream(split).map(String::trim).collect(Collectors.toList());
//                excelTable.getFieldGroups().add(groupList);
            }
            return;
        }
        if (s.equals("rule")) {
            //升序排
            int size = rowData.size();
            for (int i = 1; i < size; i++) {
                String ruleStr = rowData.get(i);
                if(ruleStr!=null){
                    String[] split = ruleStr.split(";");
                    List<String> ruleList = Arrays.stream(split).map(String::trim).collect(Collectors.toList());
//                    excelTable.getFieldRulesStr().add(ruleList);
                }else {
//                    excelTable.getFieldRulesStr().add(new ArrayList<>());
                }

            }
            return;
        }
        if (s.equals("riled_desc")) {
            //升序排
            int size = rowData.size();
            for (int i = 1; i < size; i++) {
//                excelTable.getFieldDesc().add(rowData.get(i));
            }
            return;
        }
    }

    public String errorCellMsg(String filePath, String sheetName, int rowNum, int colNum) {
        return "  excel文件：" + filePath + "; sheet名：" + sheetName + " 行号：" + rowNum + " 列号：" + colNum;
    }

    private void handleRow1(Map<Integer, String> rowData, AnalysisContext analysisContext) {
        String absolutePath = analysisContext.readWorkbookHolder().getFile().getAbsolutePath();
//        excelTable.setExcelFilePath(absolutePath);
//        String sheetName = analysisContext.readSheetHolder().getSheetName();
//        excelTable.setSheetName(sheetName);
//        int prefixLen = baseConfig.getTablePrefix().length();
//        int suffixLen = baseConfig.getTableSuffix().length();
//        String tableName = sheetName.substring(prefixLen);
//        tableName = tableName.substring(0, tableName.length() - suffixLen);
//        excelTable.setTableName(tableName);
//        //TODO 去掉前后缀 ，检查ExcelTableManager中是否已经有此表格了（分表？）
//        //数据起始行
//        String dataRowNumStr = rowData.get(0);
//        try {
//            dataRowNum = Integer.parseInt(dataRowNumStr);
//            if (dataRowNum < 2) {
//                canContinue = false;
//                ExcelTools.addErrorMsg("数据起始行配置错误，不能小于2:" + errorCellMsg(absolutePath, sheetName, rowNum, 0));
//            }
//        } catch (Exception e) {
//            canContinue = false;
//            ExcelTools.addErrorMsg("数据起始行解析失败:" + errorCellMsg(absolutePath, sheetName, rowNum, 0));
//            return;
//        }
//        excelTable.setDataStartRowNum(dataRowNum);
//        //表中文名
//        excelTable.setTableName_CN(rowData.get(1));
//        //表类型
//        String tableTypeStr = rowData.get(2);
//        if(tableTypeStr.toLowerCase().equals(Constant.TableType.Horizontal)){
//            excelTable.setTableType(Constant.TableType.Horizontal);
//        }else if(tableTypeStr.toLowerCase().equals(Constant.TableType.Vertical)){
//            excelTable.setTableType(Constant.TableType.Vertical);
//        }else {
//            excelTable.setTableType(Constant.TableType.Horizontal);
//            ExcelTools.addErrorMsg("未知的表类型："+tableTypeStr+" 使用默认值horizontal;  目前只支持横表："+Constant.TableType.Horizontal+" 和竖表："+Constant.TableType.Vertical+" 文件名："+excelTable.getExcelFilePath()+"  sheet名："+excelTable.getSheetName());
//        }
//        //分表需要
//        String spliteTableNumStr = rowData.get(3);
//        int spliteTableNum = 0;
//        try {
//            spliteTableNum = Integer.parseInt(spliteTableNumStr);
//        } catch (Exception e) {
//            if(!spliteTableNumStr.isEmpty()){
//                ExcelTableManager.task.setCanContinue(false);
//                canContinue = false;
//                ExcelTools.addErrorMsg("分表需要解析错误："+errorCellMsg(absolutePath, sheetName, rowNum, 3));
//                return;
//            }
//        }
//        excelTable.setSpliteTableNum(spliteTableNum);
////        excelTable.setTableName();
//        //其他
//        int size = rowData.size();
//        for (int i = 0; i < size; i++) {
//            if(rowData.get(i)!=null){
//                excelTable.getRow1AllParams().add(rowData.get(i));
//            }
//        }

    }

    @Override
    public boolean hasNext(AnalysisContext context) {
        return canContinue;
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        //TODO 放入管理器容器中，判断是否要合并
//        if(excelTable.getSpliteTableNum()==0){//单表
//            ExcelTableManager.tableName2ExcelTable.put(excelTable.getTableName(), excelTable);
//        }else{//分表
//
//            List<ExcelTable> excelTables = ExcelTableManager.spliteTables.get(excelTable.getTableName());
//            if(excelTables==null){
//                excelTables = new ArrayList<>();
//                ExcelTableManager.spliteTables.put(excelTable.getTableName(), excelTables);
//            }
//            if(excelTables.isEmpty()){
//                excelTables.add(excelTable);
//                return;
//            }
//            for (ExcelTable table : excelTables) {//比较分表需要
//                if(table.getSpliteTableNum()==excelTable.getSpliteTableNum()){
//                    ExcelTableManager.task.setCanContinue(false);
//                    ExcelTools.addErrorMsg("分表序号不能相同，表明分表为："+excelTable.getExcelFilePath()+"---"+table.getExcelFilePath());
//                    return;
//                }
//            }
//            //比较字段结构
//            ExcelTable other = excelTables.get(0);
//
//            List<String> filedNames = other.getFieldNames();
//            if(filedNames.size()!=excelTable.getFieldNames().size()){
//                ExcelTableManager.task.setCanContinue(false);
//                ExcelTools.addErrorMsg("分表的字段数量不一致！表名："+excelTable.getTableName()+" 文件名分表为："+excelTable.getExcelFilePath()+";"+other.getExcelFilePath());
//                return;
//            }
//            for (int i = 0; i < filedNames.size(); i++) {
//                //字段名
//                String ohterFiledName = filedNames.get(i);
//                String nowFiledName = excelTable.getFieldNames().get(i);
//                if(!ohterFiledName.equals(nowFiledName)){
//                    ExcelTableManager.task.setCanContinue(false);
//                    ExcelTools.addErrorMsg("分表的字段名不一致！表名："+excelTable.getTableName()+" 文件名分表为："+excelTable.getExcelFilePath()+";"+other.getExcelFilePath()+"字段所在列："+(i+1));
//                    return;
//                }
//                //字段类型
//                if(!other.getFieldTypes().get(i).equals(excelTable.getFieldTypes().get(i))){
//                    ExcelTableManager.task.setCanContinue(false);
//                    ExcelTools.addErrorMsg("分表的字段类型不一致！表名："+excelTable.getTableName()+" 文件名分表为："+excelTable.getExcelFilePath()+";"+other.getExcelFilePath()+"字段名："+ohterFiledName);
//                    return;
//                }
//            }
//            excelTables.add(excelTable);
//        }
    }
}
